package com.example.administrator.equipmentbledemo;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.le.ScanRecord;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.ParcelUuid;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.utils.HexUtil;
import com.example.administrator.equipmentbledemo.comm.ObserverManager;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView tv_title;
    private Button btn_search, btn_send;
    private TextView tv_receive;
    private static final int REQUEST_CODE_OPEN_GPS = 1;
    private static final int REQUEST_CODE_PERMISSION_LOCATION = 2;
    //搜索到的设备
    private List<ScanResult> scanResultList = new ArrayList<>();
    //服务选项
    private List<BluetoothGattService> buBluetoothGattServicesList = new ArrayList<>();
    //蓝牙服务
    private BleDevice bleDeviceConnect;
    private BluetoothGattService services = null;
    private String uuid_service, uuid_characteristic_write;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BleManager.getInstance().init(getApplication());
        BleManager.getInstance()
                .enableLog(true)
                .setReConnectCount(1, 5000)
                .setConnectOverTime(20000)
                .setOperateTimeout(5000);
        checkPermissions();
        initView();
    }

    private void initView() {
        tv_title = findViewById(R.id.tv_title);
        btn_search = findViewById(R.id.btn_search);
        btn_search.setOnClickListener(this);
        btn_send = findViewById(R.id.btn_send);
        btn_send.setOnClickListener(this);
        tv_receive = findViewById(R.id.tv_receive);

    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.btn_search:
                //搜索设备并且自动连接设备
                checkPermissions();
                break;
            case R.id.btn_send:
                //发送数据给设备，command是要发送的指令,在这里是写字符串，不能为空
                String command = "0000000000";
                Log.i("sdfsfsfsfsdfsdfsdfsdf", uuid_service + "##" + uuid_characteristic_write);
                BleManager.getInstance().write(
                        bleDeviceConnect,
                        uuid_service,
                        uuid_characteristic_write,
                        new BleEqupmentUtil(this, this).hexStringToBytes(command),
                        new BleWriteCallback() {
                            @Override
                            public void onWriteSuccess(int current, int total, byte[] justWrite) {

                            }

                            @Override
                            public void onWriteFailure(BleException exception) {

                            }
                        });

                break;
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        BleManager.getInstance().disconnectAllDevice();
        BleManager.getInstance().destroy();
    }


    private void checkPermissions() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!bluetoothAdapter.isEnabled()) {
            //没有打开蓝牙，强制打开蓝牙
            new BleEqupmentUtil(this, this).turnOnBluetooth();
            return;
        }

        String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};
        List<String> permissionDeniedList = new ArrayList<>();
        for (String permission : permissions) {
            int permissionCheck = ContextCompat.checkSelfPermission(this, permission);
            if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
                onPermissionGranted(permission);
            } else {
                permissionDeniedList.add(permission);
            }
        }
        if (!permissionDeniedList.isEmpty()) {
            String[] deniedPermissions = permissionDeniedList.toArray(new String[permissionDeniedList.size()]);
            ActivityCompat.requestPermissions(this, deniedPermissions, REQUEST_CODE_PERMISSION_LOCATION);
        }
    }

    @Override
    public final void onRequestPermissionsResult(int requestCode,
                                                 @NonNull String[] permissions,
                                                 @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_CODE_PERMISSION_LOCATION:
                if (grantResults.length > 0) {
                    for (int i = 0; i < grantResults.length; i++) {
                        if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                            onPermissionGranted(permissions[i]);
                        }
                    }
                }
                break;
        }
    }

    private void onPermissionGranted(String permission) {
        switch (permission) {
            case Manifest.permission.ACCESS_FINE_LOCATION:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !checkGPSIsOpen()) {
                    new AlertDialog.Builder(this)
                            .setTitle(R.string.notifyTitle)
                            .setMessage(R.string.gpsNotifyMsg)
                            .setNegativeButton(R.string.cancel,
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            finish();
                                        }
                                    })
                            .setPositiveButton(R.string.setting,
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                            startActivityForResult(intent, REQUEST_CODE_OPEN_GPS);
                                        }
                                    })

                            .setCancelable(false)
                            .show();
                } else {
                    startScan();
                }
                break;
        }
    }

    private boolean checkGPSIsOpen() {
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        if (locationManager == null)
            return false;
        return locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER);
    }

    private void startScan() {
        BleManager.getInstance().scan(new BleScanCallback() {
            @Override
            public void onScanStarted(boolean success) {
                tv_title.setText(getString(R.string.stop_scan));
            }

            @Override
            public void onLeScan(BleDevice bleDevice) {
                super.onLeScan(bleDevice);
            }

            @Override
            public void onScanning(BleDevice bleDevice) {
                //搜索到设备回调
                if (!TextUtils.isEmpty(bleDevice.getName()))
                    Log.e("lyb==========", bleDevice.getName());
                String deviceName = bleDevice.getName();
                //判断是否存在这个蓝牙名称，如果是自家公司产品就显示出来
                if (deviceName != null) {
                    byte[] record = bleDevice.getScanRecord();
                    int rssi = bleDevice.getRssi();
                    if (deviceName.indexOf("云音乐") != -1) {
                        ScanResult scanResult = new ScanResult(bleDevice.getDevice(), rssi, record
                                , bleDevice.getTimestampNanos());
                        scanResultList.add(scanResult);
                        BleManager.getInstance().cancelScan();
                        connect(bleDevice);
                    }
                }


            }

            @Override
            public void onScanFinished(List<BleDevice> scanResultList) {
                tv_title.setText(getString(R.string.start_scan));
            }
        });
    }

    public BluetoothGattService getService(int position) {
        if (position >= buBluetoothGattServicesList.size())
            return null;
        return buBluetoothGattServicesList.get(position);
    }

    //连接设备
    private void connect(final BleDevice bleDevice) {
        BleManager.getInstance().connect(bleDevice, new BleGattCallback() {
            @Override
            public void onStartConnect() {
                //开始连接
                tv_title.setText("开始连接");
            }

            @Override
            public void onConnectFail(BleDevice bleDevice, BleException exception) {
                tv_title.setText(getString(R.string.connect_fail) + "，设备" + getString(R.string.connect_fail));
            }

            @SuppressLint("NewApi")
            @Override
            public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
                tv_title.setText("已连接");
                bleDeviceConnect = bleDevice;
                //连接成功
//                BluetoothGatt gatt = BleManager.getInstance().getBluetoothGatt(bleDevice);
                buBluetoothGattServicesList.clear();
                for (BluetoothGattService service : gatt.getServices()) {
                    //添加服务
                    buBluetoothGattServicesList.add(service);
                    services = service;
                }
                //根据自己的硬件协议选择通信服务,根据我的硬件协议来选择0，第一个服务是读取设备数据，1是第二个服务发送指令控制设备
                BluetoothGattService sendService = getService(0);

                int charaProp = 0;
                //选择特性，根据自己的硬件协议修改自己的产品蓝牙特性
                List<BluetoothGattCharacteristic> characteristics = sendService.getCharacteristics();
//                List<BluetoothGattCharacteristic> mCharacteristicsList = characteristics;
//                BluetoothGattCharacteristic characteristicBle = services.getCharacteristic(sendService.getUuid());
//                for (BluetoothGattCharacteristic characteristic : sendService.getCharacteristics()) {
//                    charaProp = characteristic.getPermissions();
//                    characteristicBle = characteristic;
//                    mCharacteristicsList.add(characteristicBle);
//                }
                uuid_service = sendService.getUuid().toString();
                uuid_characteristic_write = characteristics.get(0).getUuid().toString();
                //接收通知，接收硬件返回的数据
                openNotify();
                Log.e("lyb===========", gatt.getDevice().getName() + "");
            }

            @Override
            public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
                //连接断开
                tv_title.setText("连接断开了,请重新连接");
                if (!isActiveDisConnected) {
                    ObserverManager.getInstance().notifyObserver(bleDevice);
                }
            }
        });
    }

    /**
     * 接收通知，接收硬件返回的数据
     */
    private void openNotify() {
        //根据自己的硬件协议选择通信服务,根据我的硬件协议来选择0，第一个服务是读取设备数据，1是第二个服务发送指令控制设备
        BluetoothGattService readService = getService(0);

        //选择特性，根据自己的硬件协议修改自己的产品蓝牙特性
        int charaProp = 0;
        List<BluetoothGattCharacteristic> characteristics = readService.getCharacteristics();
        BluetoothGattCharacteristic characteristicBle = services.getCharacteristic(readService.getUuid());
//        for (BluetoothGattCharacteristic characteristic : readService.getCharacteristics()) {
//            charaProp = characteristic.getPermissions();
//            characteristicBle = characteristic;
//            characteristics.add(characteristicBle);
//        }
        String uuid_read_service = readService.getUuid().toString();
        String uuid_read_characteristic_write = characteristics.get(0).getUuid().toString();
        final BleEqupmentUtil bleEqupmentUtil = new BleEqupmentUtil(this, this);
        //接收通知
        BleManager.getInstance().notify(
                bleDeviceConnect,
                uuid_read_service,
                uuid_read_characteristic_write,
                new BleNotifyCallback() {
                    @Override
                    public void onNotifySuccess() {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.i("fsdfsf", "notify success");
                            }
                        });
                    }


                    @Override
                    public void onNotifyFailure(final BleException exception) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.i("fsdfsf", exception.toString());
                            }
                        });
                    }

                    @Override
                    public void onCharacteristicChanged(final byte[] data) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                //收到硬件通知回调
                                Log.i("sfdsfsfsfsfd", HexUtil.formatHexString(data));
                                bleEqupmentUtil.addText(tv_receive, HexUtil.formatHexString(data));
                            }
                        });
                    }
                });
    }
}
